;;; core.el --- .Emacs Configuration -*- lexical-binding: t -*-
;;; Commentary:
;;

;;; Code:
(defvar org-dir  "~/org/"
  "Archivos de tareas varias ORG.")

(defvar org-imagenes-dir (concat org-dir "imagenes/")
  "Archivos de imagenes descargadas por ORG.")

(defvar workspace-dir "~/Workspace/"
  "Carpeta de trabajos y practicas.")

(defvar latex-dir  (concat workspace-dir "LaTeX/")
  "Archivos LaTeX.")

(defvar w-org-dir  (concat workspace-dir "org/")
  "Archivos escritos ORG .")

(defvar backup-dir (concat user-emacs-directory ".backup/")
  "Aquí se guardan los backups generados.")

(defvar cache-dir (concat user-emacs-directory ".cache/")
  "Archivos volatiles.")

(defvar etc-dir (concat user-emacs-directory ".etc/")
  "Archivos de uso continuo.")

(defvar local-dir (concat user-emacs-directory ".local/")
  "Carpeta local para almacenar archivos que no se tocaran.")

(defvar backup-tramp-dir (concat backup-dir "tramp/")
  "Archivos tramp.")

(defvar cache-server-dir (concat cache-dir "server/")
  "Almacen de server's.")

(defvar tramp-dir (concat cache-dir "tramp/")
  "Tramp.")

(defvar cache-tramp-dir (concat cache-dir "tramp-auto-save/")
  "Sesiones ssh guardadas.")

(defvar cache-url-dir (concat cache-dir "url/")
  "URL's volatiles.")

(defvar shared-game-score-dir (concat etc-dir "shared-game-score/")
  "Score de los juegos.")

(defvar url-dir (concat etc-dir "url/")
  "Almacen de URL's importantes.")

(defvar bookmark-dir (concat local-dir "bookmark/")
  "Bookmark Save.")

(defvar packages-dir (concat local-dir "packages/")
  "Paquetes instalados.")

(defvar projectile-dir (concat local-dir "projectile/")
  "Projectile Save.")

(dolist
    (dir
     (list org-dir
           org-imagenes-dir
           workspace-dir
           latex-dir
           w-org-dir
           backup-dir
           cache-dir
           etc-dir
           local-dir
           backup-tramp-dir
           cache-server-dir
           tramp-dir
           cache-tramp-dir
           cache-url-dir
           shared-game-score-dir
           url-dir
           bookmark-dir
           packages-dir
           projectile-dir))

  (unless (file-directory-p dir)
    (make-directory dir t)))

(setq-default
 backup-directory-alist (list (cons ".*" backup-dir))
 auto-save-list-file-prefix backup-dir
 auto-save-file-name-transforms `((".*" , backup-dir t))
 tramp-backup-directory-alist backup-tramp-dir)

(setq-default
 auto-save-list-file-name (concat cache-dir "autosave")
 semanticdb-default-save-directory (concat cache-dir "semanticdb")
 savehist-file (concat cache-dir "history")
 eshell-directory-name (concat cache-dir "eshell" ))

(setq-default
 server-auth-dir cache-server-dir)

(setq-default
 tramp-auto-save-directory tramp-dir
 tramp-persistency-file-name (concat tramp-dir "tramp")
 tramp-persistency-file-name (concat tramp-dir "tramp-persistency.el"))

(setq-default
 tramp-auto-save-directory cache-tramp-dir)

(setq-default
 url-cache-directory cache-url-dir
 url-configuration-directory (concat cache-url-dir "url"))

(setq custom-file (concat etc-dir "custom.el"))
(load custom-file t t)

(setq-default
 shared-game-score-directory shared-game-score-dir
 gamegrid-user-score-file-directory shared-game-score-dir)

(setq-default
 url-configuration-directory url-dir)

(setq history-length 1000
      history-delete-duplicates t
      savehist-save-minibuffer-history 1
      savehist-additional-variables '(kill-ring
                                      search-ring
                                      regexp-search-ring))

(savehist-mode t)

(when (fboundp 'set-charset-priority)
  (set-charset-priority 'unicode))
(prefer-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(setq locale-coding-system 'utf-8)
(setq-default buffer-file-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-keyboard-coding-system 'utf-8)
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))

(setq-default frame-title-format (list "Emacs"))

(setq inhibit-startup-screen t
      initial-scratch-message nil
      large-file-warning-threshold 100000000
      ;; Scroll
      scroll-step 1
      scroll-conservatively 3000
      scroll-up-aggressively 0.02
      scroll-down-aggressively 0.02)

(add-hook 'window-setup-hook 'toggle-frame-maximized t)

(setq-default indent-tabs-mode nil
              tab-width 2)
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(fset 'yes-or-no-p 'y-or-n-p)
(toggle-indicate-empty-lines)
(delete-selection-mode)
(blink-cursor-mode -1)
(add-hook 'before-save-hook 'delete-trailing-whitespace)
(set-default 'truncate-lines t)
(setq visual-line-mode t)
(global-eldoc-mode -1)
(electric-pair-mode 1)

(setq major-mode 'text-mode
      current-language-environment "Spanish")

(setq-default ad-redefinition-action 'accept
              apropos-do-all t
              compilation-always-kill t
              compilation-ask-about-save nil
              compilation-scroll-output t
              confirm-nonexistent-file-or-buffer t
              enable-recursive-minibuffers nil
              idle-update-delay 2
              minibuffer-prompt-properties '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt)
              auto-save-default nil
              auto-save-list-file-prefix nil
              make-backup-files nil
              create-lockfiles nil)

(setq-default bidi-display-reordering nil
              blink-matching-paren nil
              cursor-in-non-selected-windows nil
              display-line-numbers-width 3
              frame-inhibit-implied-resize t
              fringe-indicator-alist (delq
                                      (assq 'continuation fringe-indicator-alist)
                                      fringe-indicator-alist)
              highlight-nonselected-windows nil
              image-animate-loop t
              indicate-buffer-boundaries nil
              indicate-empty-lines nil
              max-mini-window-height 0.3
              mode-line-default-help-echo nil
              mouse-yank-at-point t
              ibuffer-use-other-window t
              resize-mini-windows 'grow-only
              show-help-function nil
              split-width-threshold 160
              uniquify-buffer-name-style 'forward
              use-dialog-box nil
              visible-cursor nil
              x-stretch-cursor nil
              jit-lock-defer-time nil
              jit-lock-stealth-nice 0.1
              jit-lock-stealth-time 0.2
              jit-lock-stealth-verbose nil
              pos-tip-internal-border-width 6
              pos-tip-border-width 1
              ring-bell-function #'ignore
              visible-bell nil)

(setq-default explicit-shell-file-name "/bin/bash"
              shell-file-name "/bin/bash")

;;
;; Functions
;;

(defun auto-revert-mode ()
  "Recargar todos los buffers abiertos."
  (interactive)
  (dolist (buf (buffer-list))
    (with-current-buffer buf
      (when (and (buffer-file-name) (file-exists-p (buffer-file-name)) (not (buffer-modified-p)))
        (revert-buffer t t t) )))
  (message "Refreshed open files."))

(defun duplicate-current-line-or-region (arg)
  "Duplicates the current line or region ARG times."
  (interactive "p")
  (let (beg end (origin (point)))
    (if (and mark-active (> (point) (mark)))
        (exchange-point-and-mark))
    (setq beg (line-beginning-position))
    (if mark-active
        (exchange-point-and-mark))
    (setq end (line-end-position))
    (let ((region (buffer-substring-no-properties beg end)))
      (dotimes (i arg)
        (goto-char end)
        (newline)
        (insert region)
        (setq end (point)))
      (goto-char (+ origin (* (length region) arg) arg)))))

(defun empty-buffer? ()
  "Empty Buffer."
  (= (buffer-end 1) (buffer-end -1)))

(defconst rakso-homepage
  "https://notabug.org/raksodiano/Emacs"
  "The Notabug page of Emacs.")

(defun browse-homepage ()
  "Browse The Notabug page of Emacs."
  (interactive)
  (browse-url rakso-homepage))

(defun open-custom-file()
  "Open custom.el if exists, otherwise create it."
  (interactive)
  (let ((custom-example
         (expand-file-name "custom-example.el" user-emacs-directory)))
    (unless (file-exists-p custom-file)
      (if (file-exists-p custom-example)
          (copy-file custom-file)
        (error "Unable to find \"%s\"" custom-example)))
    (find-file custom-file)))

(defun rakso-split-window-vertically ()
  "Divide la ventana por la mitad verticalmente y mueve el cursor a la ventana nueva"
  (interactive)
  (split-window-vertically)
  (other-window 1))

(defun rakso-split-window-horizontally ()
  "Divide la ventana por la mitad horizontalmente y mueve el cursor a la ventana nueva"
  (interactive)
  (split-window-horizontally)
  (other-window 1))

(global-set-key [remap split-window-below] #'rakso-split-window-vertically)
(global-set-key [remap split-window-right] #'rakso-split-window-horizontally)

(load-file (concat user-emacs-directory "core/core-packages.el"))

;;
;; Carga de todos los archivos dinamicamente
;;

(eval-when-compile
  (defun file-name-is-elisp? (file-name)
    "Say if the extension of a FILE NAME implies Emacs Lisp code.
This is done by checking if the extension is present in
`load-suffixes'."
    (let ((file-suffix (concat "." (downcase (file-name-extension file-name))))
          (emacs-lisp-suffixes (mapcar 'downcase load-suffixes)))
      (if (member file-suffix emacs-lisp-suffixes) t nil)))

  (defun load-directory (directory &optional recursive)
    "Load the Emacs Lisp files in a DIRECTORY.
Operate recursively in its subdirectories if RECURSIVE is non-nil."
    (let ((visited nil))
      (dolist (name (directory-files directory t))
        (if (not (string-match "/\\.[^/]*$" name))
            (if (file-directory-p name)
                (when recursive (load-directory name t))
              (when (file-name-is-elisp? name)
                (let ((file (file-name-sans-extension name)))
                  (unless (member file visited)
                    (push file visited)
                    (load file)))))))))

  (load-directory (expand-file-name "modules/" user-emacs-directory) t))

(provide 'core)
;;; core.el ends here
